vimfandomcom-20200223-history
Page up/down and keep cursor position
Borland behaviour = the cursor keeps the same xy position during pageup/down. I'm new to Vim scripting, im sure it can be done smarter? I read VimTip105 and it gave me a clue of how BorlandPageUp/Down could be done. " i could'nt find any get_number_of_visible_lines function, so i made my own. function GetNumberOfVisibleLines() let cur_line = line(".") let cur_col = virtcol(".") normal H let top_line = line(".") normal L let bot_line = line(".") execute "normal " . cur_line . "G" execute "normal " . cur_col . "|" return bot_line - top_line endfunc " noremap 39:set scroll=0 function! MyPageUp() let visible_lines = GetNumberOfVisibleLines() execute "normal " . visible_lines . "\:set scroll=0\r" endfunction " noremap 39:set scroll=0 function! MyPageDown() let visible_lines = GetNumberOfVisibleLines() execute "normal " . visible_lines . "\:set scroll=0\r" endfunction " BorlandPascal pageup/down behaviour! " todo: when hitting top/bottom of file, then restore Y to lastY noremap :call MyPageUp() noremap :call MyPageDown() Comments For maintaining the same x coordinate, . ---- And CTRL-U (up), CTRL-D (down) may also be useful for what you want (half page scrolls) ---- A solution that I use (easier, I would say, but has a small side-effect) is this: map :set scroll=0:set scroll^=2:set scroll-=1:set scroll=0 map :set scroll=0:set scroll^=2:set scroll-=1:set scroll=0 I found Vim's normal PgUp/PgDn behaviour weird - I think it's different from every other editor I've used and I was unable to get used to it. The above two lines are godsent! Ditto on the above two lines. They work exactly as I want! (SRS) ---- See Combining move and scroll. You might find it useful to incorporate the improvements into this tip. ---- A solution that works in insert and visual modes too: nnoremap vnoremap inoremap nnoremap vnoremap inoremap It assumes that "scroll" has its default value. Also there is an intermediate redraw, but that could be perceived as a feature, really. I've spent a whole day trying to simulate sometheing like the command for Visual mode (hoping for the universal solution -- a way to call any normal mode command from any mode), yet it looks like impossible if the command in question is supposed to be a custom movement command, modifying selection. ---- Another method that does not move cursor from screen position when scrolling, even with long lines that wrap: function! s:GetNumScroll(num) let num_rows = winheight(0) let num_scroll = a:num if (a:num -1) let num_scroll = (num_rows + 1) / 2 elseif (a:num -2) let num_scroll = num_rows endif if (num_scroll < 1) let num_scroll = 1 endif return num_scroll endfunction function! s:RtrnToOrig(before_scr_line) normal H let delta = a:before_scr_line - winline() while (delta != 0) if (delta < 0) let delta = winline() - a:before_scr_line let iter = 1 while (iter <= delta) execute "normal" "gk" let iter +=1 endwhile elseif (delta > 0) let iter = 1 while (iter <= delta) execute "normal" "gj" let iter +=1 endwhile endif let delta = a:before_scr_line - winline() endwhile endfunction function! s:scrollUP(num) let num_scroll = GetNumScroll(a:num) let num_rows = winheight(0) " ------------- let before_scr_line = winline() normal L let after_scr_line = winline() let extra = num_rows - after_scr_line let extra += num_scroll " move by 1 to prevent over scrolling let iter = 1 while (iter <= extra) execute "normal" "gj" let iter +=1 endwhile " ------------- call RtrnToOrig(before_scr_line) endfunction function! s:scrollDN(num) let num_scroll = GetNumScroll(a:num) " ------------- let before_scr_line = winline() normal H let after_scr_line = line(".") execute "normal" "gk" let after_scr2_line = line(".") if ( (after_scr_line after_scr2_line) && (after_scr_line > 1) ) execute "normal" "gk" endif let extra = (num_scroll - 1) let extra += (winline() - 1) " move by 1 to prevent over scrolling let iter = 1 while (iter <= extra) execute "normal" "gk" let iter +=1 endwhile " ------------- call RtrnToOrig(before_scr_line) endfunction nmap :call scrollUP(1) nmap :call scrollDN(1) nmap :call scrollUP(-1) nmap :call scrollDN(-1) nmap :call scrollUP(-2) nmap :call scrollDN(-2)